package controller

import (
	"digital/server/common"
	"digital/server/model"
	"digital/server/response"
	"github.com/gin-gonic/gin"
	"github.com/jinzhu/gorm"
	"net/http"
	"sort"
)

// 返回所有消息
func GetAllMesg(ctx *gin.Context) {
	DB := common.GetDB()
	account := ctx.Query("account")

	var mesgRecords []model.Message // 存储mesg表中的完整记录，用于后续提取详细信息

	// 从mesg表中获取mid, sid, lid, extra_content, state, mtime
	result := DB.Table("msg").Where("rid = ?", account).Order("mtime ASC").Find(&mesgRecords)
	if result.Error != nil {
		response.Response(ctx, http.StatusInternalServerError, 500, nil, "查询消息记录时出错："+result.Error.Error())
		return
	}
	if len(mesgRecords) == 0 {
		response.Response(ctx, http.StatusNotFound, 404, nil, "暂时未有消息!")
		return
	}
	var systemFiles []model.AllFile
	if err := DB.Table("all_file").Where("id BETWEEN 0 AND 9").Find(&systemFiles).Error; err != nil {
		response.Response(ctx, http.StatusInternalServerError, 500, nil, "查询系统消息头像文件失败："+err.Error())
		return
	}
	var messages []model.MessageToUser //传给用户的信息
	for _, msgRecord := range mesgRecords {
		var msg_sender model.MsgSender
		if err := DB.Table("msg_sender").Where("id = ?", msgRecord.Sid).First(&msg_sender).Error; err != nil {
			response.Response(ctx, http.StatusInternalServerError, 500, nil, "查询消息发送者表失败失败!")
			return
		}
		var system_info model.SystemInfo
		if err := DB.Table("system_msg").Where("lid = ?", msgRecord.Lid).First(&system_info).Error; err != nil {
			response.Response(ctx, http.StatusInternalServerError, 500, nil, "查询系统消息表失败失败!")
			return
		}
		var user model.User
		if err := DB.Table("users").Where("uid = ?", msgRecord.Approver).First(&user).Error; err != nil {
			response.Response(ctx, http.StatusInternalServerError, 500, nil, "查询审批人信息失败失败!")
			return
		}
		detailledMsg := model.MessageToUser{
			Mid:          msgRecord.Mid,
			Avatar:       systemFiles[msg_sender.Type].FileUrl,
			Type:         msg_sender.Type,
			RelatedName:  msg_sender.SName,
			Info:         system_info.Info,
			ExtraContent: msgRecord.ExtraContent,
			State:        msgRecord.State,
			ApproverID:   msgRecord.Approver,
			ApproverName: user.Uname,
			Mtime:        msgRecord.Mtime,
		}
		messages = append(messages, detailledMsg)
	}
	response.Success(ctx, gin.H{"messages": messages}, "消息获取成功!")
}

// 返回所有消息
func GetAllMesgType(ctx *gin.Context) {
	DB := common.GetDB()
	account := ctx.Query("account")

	var mesgRecords []model.Message // 存储mesg表中的完整记录，用于后续提取详细信息

	// 从mesg表中获取mid, sid, lid, extra_content, state, mtime
	result := DB.Table("msg").Where("rid = ?", account).Order("mtime ASC").Find(&mesgRecords)
	if result.Error != nil {
		if gorm.IsRecordNotFoundError(result.Error) {
			response.Response(ctx, http.StatusOK, 200, nil, "暂时没有消息：")
			return
		} else {
			response.Response(ctx, http.StatusInternalServerError, 500, nil, "查询消息记录时出错："+result.Error.Error())
			return
		}
	}
	var systemFiles []model.AllFile
	if err := DB.Table("all_file").Where("id BETWEEN 0 AND 9").Find(&systemFiles).Error; err != nil {
		response.Response(ctx, http.StatusInternalServerError, 500, nil, "查询系统消息头像文件失败："+err.Error())
		return
	}

	// 创建一个map来存储每种类型的消息列表和未读消息数量
	typeMessages := make(map[int]struct {
		Messages    []model.MessageToUser
		UnreadCount int
	})

	var totalcount int
	for _, msgRecord := range mesgRecords {
		var msg_sender model.MsgSender
		if err := DB.Table("msg_sender").Where("id = ?", msgRecord.Sid).First(&msg_sender).Error; err != nil {
			response.Response(ctx, http.StatusInternalServerError, 500, nil, "查询消息发送者表失败!")
			return
		}

		var system_info model.SystemInfo
		if err := DB.Table("system_msg").Where("lid = ?", msgRecord.Lid).First(&system_info).Error; err != nil {
			response.Response(ctx, http.StatusInternalServerError, 500, nil, "查询系统消息表失败!")
			return
		}

		var user model.User
		if err := DB.Table("users").Where("uid = ?", msgRecord.Approver).First(&user).Error; err != nil {
			response.Response(ctx, http.StatusInternalServerError, 500, nil, "查询审批人信息失败!")
			return
		}

		// 创建消息详细信息
		detailledMsg := model.MessageToUser{
			Mid:          msgRecord.Mid,
			Avatar:       systemFiles[msg_sender.Type].FileUrl,
			Type:         msg_sender.Type,
			RelatedName:  msg_sender.SName,
			RID:          msgRecord.Rid,
			Info:         system_info.Info,
			ExtraContent: msgRecord.ExtraContent,
			State:        msgRecord.State,
			ApproverID:   msgRecord.Approver,
			ApproverName: user.Uname,
			Mtime:        msgRecord.Mtime,
		}

		// 初始化typeMessages条目（如果尚未初始化）
		if _, exists := typeMessages[msg_sender.Type]; !exists {
			typeMessages[msg_sender.Type] = struct {
				Messages    []model.MessageToUser
				UnreadCount int
			}{}
		}

		// 获取当前类型的消息条目
		entry := typeMessages[msg_sender.Type]

		// 将消息添加到对应类型的消息列表中
		entry.Messages = append(entry.Messages, detailledMsg)

		// 如果消息未读（假设State == 0表示未读），增加未读计数
		if msgRecord.State == 0 {
			entry.UnreadCount++
			totalcount++
		}

		// 将更新后的条目重新赋值回map
		typeMessages[msg_sender.Type] = entry
	}

	// 将结果转换为需要的格式
	var categorizedMessages []gin.H
	typeNames := []string{"加入社团", "加入活动", "社团年检", "社团评优", "创建社团", "举办活动", "退出社团", "发布年检", "发布评优", "活动通知"}
	for i := 0; i <= 9; i++ {
		if msg, exists := typeMessages[i]; exists {
			categorizedMessages = append(categorizedMessages, gin.H{
				"type":         i,
				"type_name":    typeNames[i],
				"avatar":       systemFiles[i].FileUrl,
				"messages":     msg.Messages,
				"unread_count": msg.UnreadCount,
			})
		}
	}
	// 按未读消息数量排序，将未读数量大于0的放在前面
	sort.Slice(categorizedMessages, func(i, j int) bool {
		return categorizedMessages[i]["unread_count"].(int) > categorizedMessages[j]["unread_count"].(int)
	})
	response.Success(ctx, gin.H{"messages": categorizedMessages, "totalunread": totalcount}, "消息获取成功!")
}

type MarkAsReadRequest struct {
	MessageIds []int `json:"messageIds"`
}

func MarkAsRead(ctx *gin.Context) {
	db := common.GetDB()
	var request MarkAsReadRequest
	if err := ctx.BindJSON(&request); err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request"})
		return
	}
	// 开始事务
	tx := db.Begin()

	for _, messageID := range request.MessageIds {
		result := tx.Table("msg").Where("mid=?", messageID).Updates(model.Message{
			State: 1,
		})
		if result.Error != nil {
			tx.Rollback()
			response.Response(ctx, http.StatusInternalServerError, 500, nil, "更新消息状态失败!")
			return
		}
	}
	// 提交事务
	if err := tx.Commit().Error; err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to commit transaction"})
		return
	}
	response.Success(ctx, gin.H{"msg": "更新消息状态成功!"}, "更新消息状态成功!")
}
